package com.szholly.data.common.util;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.szholly.utils.util.StringUtils;
import com.szholly.utils.util.TreeDataNode;
import com.szholly.data.general.GlobalDataType;
import com.szholly.data.general.RowBase;

/**
 * 定义构造树型结构算法类
 */
public class TreeDataUtils {
	
	/**
	 * 获取树型结构数据
	 */
	@SuppressWarnings("unchecked")
	public static List<Map<String, Object>> GetTreeData(List<RowBase> dataSource,
			String idField, String pidField, String isChildField, String valueField, String textField) {
		if (dataSource == null || dataSource.size() <= 0)
			return null;
		// LinkedHashMap
		if (StringUtils.IsNullOrSpace(idField)
				|| StringUtils.IsNullOrSpace(pidField)) {
			List<Map<String, Object>> resutl = new ArrayList<Map<String, Object>>();
			for (RowBase row : dataSource) {
				if (row == null)
					continue;
				Map<String, Object> node = new LinkedHashMap<String, Object>();
				node.putAll(row);
				Object idObject = row.getValue(valueField);
				if(idObject==null){
					throw new RuntimeException("字段【" + valueField + "】值不能为空！");
				}
				node.put("id", idObject.toString());
				node.put("text", row.getValue(textField).toString());
				if(isChildField==null){
					node.put("state", "open");
				}else{
					Object isChild = node.get(isChildField);
					if(isChild==null || isChild.toString().equals("0") || isChild.toString().equals("")){
						node.put("state", "closed");
					}else{
						node.put("state", "open");
					}
				}
				resutl.add(node);
			}
			return resutl;
		}

		// 已知的ID集
		LinkedHashMap<String, Map<String, Object>> idDic = new LinkedHashMap<String, Map<String, Object>>();
		// 未知的ID集
		LinkedHashMap<String, Map<String, Object>> noIdDic = new LinkedHashMap<String, Map<String, Object>>();

		for (RowBase row : dataSource) {
			if (row == null)
				continue;
			String id = (String) row.getValue(GlobalDataType.String, idField);
			if (StringUtils.IsNullOrSpace(id))
				continue;

			// 已经存在，不处理
			if (idDic.containsKey(id))
				continue;

			// 在未知集中
			Map<String, Object> node = null;
			if (noIdDic.containsKey(id)) {
				node = noIdDic.get(id);
				node.putAll(row);
				Object idObject = row.getValue(valueField);
				if(idObject==null){
					throw new RuntimeException("字段【" + valueField + "】值不能为空！");
				}
				node.put("id", idObject.toString());
				node.put("text", row.getValue(textField).toString());
				if(node.containsKey("state")){
					node.remove("state");
				}
				node.put("state", "open");
				idDic.put(id, node);
				noIdDic.remove(id);
			} else {
				node = new LinkedHashMap<String, Object>();
				node.putAll(row);
				Object idObject = row.getValue(valueField);
				if(idObject==null){
					throw new RuntimeException("字段【" + valueField + "】值不能为空！");
				}
				node.put("id", idObject.toString());
				node.put("text", row.getValue(textField).toString());
				if(isChildField==null){
					if(node.containsKey("state")){
						node.remove("state");
					}
					node.put("state", "open");
				}else{
					Object isChild = node.get(isChildField);
					if(isChild==null || isChild.toString().equals("0") || isChild.toString().equals("")){
						node.put("state", "closed");
					}else{
						node.put("state", "open");
					}
				}
				idDic.put(id, node);
			}

			String pid = (String) row.getValue(GlobalDataType.String, pidField);
			if (StringUtils.IsNullOrSpace(pid))
				pid = "00000000000000000000000";

			// 上级项在已知对象中
			if (idDic.containsKey(pid)) {
				List<Map<String, Object>> children = null;
				if(!idDic.get(pid).containsKey("children")){
					children = new ArrayList<Map<String, Object>>();
					idDic.get(pid).put("children", children);
				}else{
					children = (List<Map<String, Object>>)idDic.get(pid).get("children");
				}
				children.add(node);
				if(idDic.get(pid).containsKey("state")){
					idDic.get(pid).remove("state");
				}
				idDic.get(pid).put("state", "closed");
			} else {
				// 在未处理对象中
				if (noIdDic.containsKey(pid)) {
					List<Map<String, Object>> children = null;
					if(!noIdDic.get(pid).containsKey("children")){
						children = new ArrayList<Map<String, Object>>();
						noIdDic.get(pid).put("children", children);
					}else{
						children = (List<Map<String, Object>>)noIdDic.get(pid).get("children");
					}
					children.add(node);
					if(noIdDic.get(pid).containsKey("state")){
						noIdDic.get(pid).remove("state");
					}
					noIdDic.get(pid).put("state", "closed");
				} else {
					Map<String, Object> pnode = new LinkedHashMap<String, Object>();
					List<Map<String, Object>> children = new ArrayList<Map<String, Object>>();
					pnode.put("children", children);
					children.add(node);
					noIdDic.put(pid, pnode);
				}
			}
		}

		// 返回集
		List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
		Set<String> noIdDicKeys = noIdDic.keySet();
		for (String key : noIdDicKeys) {
			List<Map<String, Object>> item =  (List<Map<String, Object>>)noIdDic.get(key).get("children");
			if(item!=null && item.size()>0){
				resultList.addAll(item);
			}
		}
		return resultList;
	}

	/**
	 * 获取树型结构数据
	 */
	public static List<TreeDataNode> GetTreeData(List<RowBase> dataSource,
			String idField, String pidField, String valueField, String textField) {
		if (dataSource == null || dataSource.size() <= 0)
			return null;

		if (StringUtils.IsNullOrSpace(idField)
				|| StringUtils.IsNullOrSpace(pidField)) {
			List<TreeDataNode> resutl = new ArrayList<TreeDataNode>();
			for (RowBase row : dataSource) {
				if (row == null)
					continue;
				TreeDataNode node = new TreeDataNode();
				node.setAttributes(row);
				node.setid(row.getValue(valueField).toString());
				node.setText(row.getValue(textField).toString());
				node.setState("open");
				resutl.add(node);
			}
			return resutl;
		}

		// 已知的ID集
		LinkedHashMap<String, TreeDataNode> idDic = new LinkedHashMap<String, TreeDataNode>();
		// 未知的ID集
		LinkedHashMap<String, TreeDataNode> noIdDic = new LinkedHashMap<String, TreeDataNode>();

		for (RowBase row : dataSource) {
			if (row == null)
				continue;
			String id = (String) row.getValue(GlobalDataType.String, idField);
			if (StringUtils.IsNullOrSpace(id))
				continue;

			// 已经存在，不处理
			if (idDic.containsKey(id))
				continue;

			// 在未知集中
			TreeDataNode node = null;
			if (noIdDic.containsKey(id)) {
				node = noIdDic.get(id);
				node.setAttributes(row);
				node.setid(row.getValue(valueField).toString());
				if(row.getValue(textField)!=null)
				node.setText(row.getValue(textField).toString());
				node.setState("open");
				idDic.put(id, node);
				noIdDic.remove(id);
			} else {
				node = new TreeDataNode();
				node.setAttributes(row);
				node.setid(row.getValue(valueField).toString());
				if(row.getValue(textField)!=null)
				node.setText(row.getValue(textField).toString());
				node.setState("open");
				idDic.put(id, node);
			}

			String pid = (String) row.getValue(GlobalDataType.String, pidField);
			if (StringUtils.IsNullOrSpace(pid))
				pid = "00000000000000000000000";

			// 上级项在已知对象中
			if (idDic.containsKey(pid)) {
				if (idDic.get(pid).getChildren() == null){
					idDic.get(pid).setChildren(new ArrayList<TreeDataNode>());
				}
				idDic.get(pid).getChildren().add(node);
				idDic.get(pid).setState("closed");
			} else {
				// 在未处理对象中
				if (noIdDic.containsKey(pid)) {
					if (noIdDic.get(pid).getChildren() == null){
						noIdDic.get(pid).setChildren(new ArrayList<TreeDataNode>());
					}
					noIdDic.get(pid).getChildren().add(node);
					noIdDic.get(pid).setState("closed");
				} else {
					TreeDataNode pnode = new TreeDataNode();
					if (pnode.getChildren() == null){
						pnode.setChildren(new ArrayList<TreeDataNode>());
					}
					pnode.getChildren().add(node);
					noIdDic.put(pid, pnode);
				}
			}
		}

		// 返回集
		List<TreeDataNode> resultList = new ArrayList<TreeDataNode>();
		Set<String> noIdDicKeys = noIdDic.keySet();
		for (String key : noIdDicKeys) {
			List<TreeDataNode> item = noIdDic.get(key).getChildren();
			if(item!=null && item.size()>0){
				resultList.addAll(item);
			}
		}
		return resultList;
	}
}
